package main

import (
	"fmt"
	"sync"
)

/*
TODO:
数组实现队列
链表实现队列

环形队列
双端队列
单端队列
*/

/**
接口
*/
type IArrayQueue interface {
	Enqueue(value interface{})
	Dequeue() interface{}
}

/**
队列结构体
*/
type ArrayQueue struct {
	//front int //队头指针
	//rear  int //队尾指针
	maxSize int           //队列的最大容量
	Data    []interface{} //切片维护队列中的数据源
	lock    sync.Mutex    //互斥锁，保证线程安全
}

/**
构造队列
*/
func NewArrayQueue(maxsize int) *ArrayQueue {
	queue := new(ArrayQueue)
	//queue.front = 0
	//queue.rear = 0
	//queue.maxSize = maxsizecls

	queue.Data = make([]interface{}, 0)
	return queue
}

/**
入队
*/
func (aq *ArrayQueue) Enqueue(value interface{}) {
	aq.lock.Lock()
	defer aq.lock.Unlock()

	//将数据入队
	aq.Data = append(aq.Data, value)
	//fmt.Println(aq.Data)
	//更新队列中的数量
	aq.maxSize = aq.maxSize + 1
}

/**
出队
*/
func (aq *ArrayQueue) Dequeue() interface{} {

	aq.lock.Lock()
	defer aq.lock.Unlock()

	if aq.maxSize == 0 {
		fmt.Println("queue empty")
		return nil
	}
	//出队
	v := aq.Data[0]

	/*
		这种处理方式需要频繁开辟内存空间
	*/

	// 创建新的数组，移动次数过多
	newArray := make([]interface{}, aq.maxSize-1, aq.maxSize-1)
	for i := 1; i < aq.maxSize; i++ {
		// 从老数组的第一位开始进行数据移动
		newArray[i-1] = aq.Data[i]
	}
	aq.Data = newArray

	// 队中元素数量-1
	aq.maxSize = aq.maxSize - 1
	return v
}

/**
队列
*/
func main() {
	var queue = NewArrayQueue(4)
	queue.Enqueue(1)
	queue.Enqueue(2)
	queue.Enqueue(3)
	queue.Enqueue(4)
	queue.Enqueue(5)
	queue.Enqueue(6)
	queue.Enqueue(7)
	queue.Enqueue(8)
	queue.Enqueue(9)
	queue.Enqueue(10)

	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
	fmt.Println(queue.Dequeue())
}
